iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Software Development

從Servlet到Spring MVC系列 第 26

Day25 Spring MVC - Review Spring Framework (2)

  • 分享至 

  • xImage
  •  

前言

如果有碰過Spring專案應該會發現annotation與xml設定的方式會混用(比如明天會看到的Spring MVC),但走到Spring boot你就會發現都會是annotaion配置方式了,先理解xml的設定方式有助於我們更快熟悉annotation設定方式,今日我們將嘗試全部使用Annotation的方式來配置物件。

0、創建package

我們沿用day24的module,在原有的package創建com.swj.annotation,好讓讀者與原先的com.swj.xml做比較

一、Annotation-based Configuration

(1) Stereotype Annotations

翻譯作刻板印象註解,在系統架構分層中可以讓我們清楚了解物件是在哪一層主要負責的功能,其實就是寫給開發人員看的。Spring並不會區分這些註解,當在IDE中點選這些註解會發現背後其實都是@Component。

  • @Controller:控制器,建議給控制器層的組件註解,例如servlet
  • @Service:業務邏輯,建議給業務邏輯層組件的註解
  • @Repository:數據庫層(持久化層,dao層)
  • @Component:不屬於以上幾層的組件所給予的註解,例如WebUtils

(2) @Bean

它只能在方法上註解,通常會設定在有@Configuration的class中,它可以在同一個class中引用其他@Bean的方法,請參考官方API說明

 @Configuration
 public class AppConfig {

     @Bean
     public FooService fooService() {
         return new FooService(fooRepository());
     }

     @Bean
     public FooRepository fooRepository() {
         return new JdbcFooRepository(dataSource());
     }

     // ...
 }

(3) @Configuration

配置文件註解,想成是前一天範例的beans.xml。只是Spring container生成時引用不同的設定檔,通常會與@ComponentScan合併使用,告訴Container哪個package下的物件也需要納管。

//生成spring container use xxx.class
AnnotationConfigApplicationContext container = new AnnotationConfigApplicationContext(SpringConfig.class);
//生成spring container use xml
ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext("beans.xml");
        

Demo

TestAnnotation

public class TestAnnotation {
    public static void main(String[] args) throws SQLException {
        AnnotationConfigApplicationContext container = new AnnotationConfigApplicationContext(SpringConfig.class);

        User bean = container.getBean(User.class);
        System.out.println(bean);

        UserController controller = container.getBean(UserController.class);
        controller.doUserController();
    }
}

SpringConfig

@Configuration
@ComponentScan(value = "com.swj.annotation")
public class SpringConfig {

    @Bean
    public User user() {
        return new User("joe", "1234"); // 注入默认值
    }

}

DbConfig
透過@PropertySource引入外部設定檔
透過@Value與${}設定參數檔資訊

@Configuration
@PropertySource("classpath:dbConfig.properties") // 引入外部設定檔
public class DbConfig {

    // 引用設定檔資訊
    @Value("${db.driverClassName}")
    private String driverClassName;

    @Value("${db.url}")
    private String url;

    @Value("${db.username}")
    private String username;

    @Value("${db.password}")
    private String password;

    @Value("${db.hikari.maximumPoolSize}")
    private int maximumPoolSize;

    @Value("${db.hikari.minimumIdle}")
    private int minimumIdle;

    @Value("${db.hikari.idleTimeout}")
    private long idleTimeout;

    @Value("${db.hikari.connectionTimeout}")
    private long connectionTimeout;

    @Value("${db.hikari.maxLifetime}")
    private long maxLifetime;

    // Config HikariCP 
    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setJdbcUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setMaximumPoolSize(maximumPoolSize);
        dataSource.setMinimumIdle(minimumIdle);
        dataSource.setIdleTimeout(idleTimeout);
        dataSource.setConnectionTimeout(connectionTimeout);
        dataSource.setMaxLifetime(maxLifetime);
        return dataSource;
    }
}

User

public class User {
    private String name;
    private String userId;

    public User(String name, String userId) {
        this.name = name;
        this.userId = userId;
        //省略getter setter toString
    }
}

UserController

@Controller
public class UserController {
    private UserService userService;

    public void doUserController() throws SQLException {
        System.out.println("in doUserController");
        userService.doUserService();
    }

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

UserService

@Service
public class UserService {
    private UserDao userDao;
    public void doUserService() throws SQLException {
        System.out.println("invoke doUserService");
        userDao.doUserDao();
    }

    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}

UserDao

@Repository
public class UserDao {
    private DataSource dataSource;
    public void doUserDao() throws SQLException {
        System.out.println("invoke doUserDao");
        System.out.println("dataSource info:"+dataSource.getConnection());
    }

    @Autowired
    public UserDao(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}

Demo
https://ithelp.ithome.com.tw/upload/images/20241010/20128084ImSF32vp2u.png

Reference


上一篇
Day24 Spring MVC - Review Spring Framework (1)
下一篇
Day26 Spring MVC - Concept
系列文
從Servlet到Spring MVC36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言